#ifndef SC_FRAME_BUFFER_H
#define SC_FRAME_BUFFER_H

#include "common.h"

#include <stdbool.h>

#include "util/thread.h"

/* 
AVFrame表示解码过后的一个数据帧，即AVFrame结构体描述了解码后的（原始）音频或视频数据
AVFrame结构体一般用于存储原始数据（即非压缩数据，例如对视频来说是YUV，RGB，对音频来说是PCM），
此外还包含了一些相关的信息
*/
// forward declarations
typedef struct AVFrame AVFrame;

// pending 待处理的

/**
 * 自定义帧缓冲上下文,只保留一个帧，如果处理不及时，新来帧时就抛弃旧帧
 * A frame buffer holds 1 pending frame, which is the last frame received from
 * the producer (typically, the decoder).
 *
 * If a pending frame has not been consumed when the producer pushes a new
 * frame, then it is lost. The intent is to always provide access to the very
 * last frame to minimize latency.
 */

struct sc_frame_buffer {
    // 接下来待处理的视频帧    
    AVFrame *pending_frame;
    AVFrame *tmp_frame; // To preserve the pending frame on error 在出错时保留挂起的帧

    // 处理帧数据时需要互斥锁保证线程安全
    sc_mutex mutex;

    // 待处理的帧数据是否已经处理
    bool pending_frame_consumed;
};

/*
初始化自定义帧缓冲
@param fb 帧缓冲上下文
@return 初始化成功返回true,否则返回false
*/
bool
sc_frame_buffer_init(struct sc_frame_buffer *fb);

/*
回收自定义帧缓冲资源
@param fb 帧缓冲上下文
*/
void
sc_frame_buffer_destroy(struct sc_frame_buffer *fb);

/*
添加一个frame到帧缓冲区中
@param fb 帧缓冲上下文
@param frame 新的帧数据
@param skipped 回写前一帧的数据是否被跳过
@return 运行成功返回true,否则返回false
*/
bool
sc_frame_buffer_push(struct sc_frame_buffer *fb, const AVFrame *frame,
                     bool *skipped);

/*
获取一个用于消费的frame并重置其中的数据
@param fb 帧缓冲上下文
@param dst 回写待处理的帧数据
*/
void
sc_frame_buffer_consume(struct sc_frame_buffer *fb, AVFrame *dst);

#endif
